using System.Collections.Generic;
using NHibernate;

namespace FwkLight.Domain.Query
{
  public abstract class CriteriaQuery<T> : CriteriaQuery<T, T>
  {
  }

  public abstract class CriteriaQuery<T, TOutput> : IDomainQuery<T, TOutput>
  {
    private ICriteria _criteria;

    protected ICriteria GetCriteria
    {
      get
      {
        return _criteria;
      }
    }

    protected IList<T> LoadList()
    {
      return _criteria.List<T>();
    }

		protected TOutput LoadUnique(ISession session)
    {
			Initialise(session, false);
    	return _criteria.UniqueResult<TOutput>();
    }

		protected IList<TOutput> Load(ISession session)
    {
      return Load(session, false);
    }

		protected IList<TOutput> Load(ISession session, bool includingInactive)
    {
      Initialise(session, includingInactive);
			return _criteria.List<TOutput>();
    }

    protected T UniqueResult()
    {
      return _criteria.UniqueResult<T>();
    }

    public IDomainQuery<T,TOutput> Initialise(ISession session)
    {
      return Initialise(session, false);
    }

    public IDomainQuery<T, TOutput> Initialise ( ISession session, bool includingInactive )
    {
      _criteria = session.CreateCriteria(typeof(T));
      GetMainCriteria(_criteria);
      if (!includingInactive)
        FilterOnlyActive(_criteria);
      Sort(_criteria);
      return this;
    }

    public virtual TOutput GetResult()
    {
      return default(TOutput);
    }

    public abstract void GetMainCriteria(ICriteria criteria);
    public abstract void FilterOnlyActive(ICriteria criteria);
    public abstract void Sort(ICriteria criteria);
  }
}